<template>
    <view>
        <u-popup v-model="params.isShow" :round="10" mode="center" border-radius="14">
            <view style="padding: 40rpx 20rpx 20rpx 20rpx">
                <view
                    :style="{
                        height: captchaRequest.bgImageHeight * props.scale + 'rpx',
                        width: captchaRequest.bgImageWidth * props.scale + 'rpx',
                        backgroundImage: 'url(' + params.captcha.bgImage + ')',
                        backgroundSize: '100% 100%',
                    }"
                >
                    <image
                        :src="params.captcha.sliderImage"
                        style="color: #4ceed6; border: #4cd964"
                        :style="{
                            left: sliderImageLeft + 'rpx',
                            height: captchaRequest.sliderImageHeight * props.scale + 'rpx',
                            width: captchaRequest.sliderImageWidth * props.scale + 'rpx',
                        }"
                        @touchstart="down"
                        @touchmove="moving"
                        @touchend="up"
                    />
                </view>
                <progress
                    :percent="((sliderImageLeft / props.scale) * 100) / (captchaRequest.bgImageWidth - captchaRequest.sliderImageWidth)"
                    activeColor="#4cd964"
                    stroke-width="6"
                ></progress>
            </view>
        </u-popup>
    </view>
</template>

<script setup lang="ts">
import { reactive, computed, PropType, watch, defineProps, defineEmits } from 'vue'
import { doGetCaptchaSlider } from '@/apis/sign'
import DateUtil from '@/utils/date'
import { ImageCaptchaTrack, CaptchaResponse, TrackType, CaptchaRequest } from './Captcha'
// import UButton from '@/uni_modules/vk-uview-ui/components/u-button/u-button.vue'
const props = defineProps({
    modelValue: {
        type: Boolean,
        required: true,
    },
    scale: {
        type: Number,
        default: 2,
    },
    smsType: {
        type: String,
        default: null,
    },
    getForm: {
        type: Function as PropType<() => any>,
        required: true,
    },
    doSubmit: {
        type: Function as PropType<(request: CaptchaRequest<any>) => Promise<any>>,
        required: true,
    },
})
const emits = defineEmits(['update:modelValue', 'success'])
const sliderImageLeft = computed(() => {
    const trackList = captchaRequest.trackList
    const length = trackList.length
    if (!trackList || length <= 0) {
        return 0
    }
    const min = 0
    const max = (captchaRequest.bgImageWidth - captchaRequest.sliderImageWidth) * props.scale
    const left = trackList[length - 1].x * props.scale
    return left <= min ? min : left >= max ? max : left
})

const params = reactive({
    isShow: true,
    sliderValue: 0,
    captcha: {
        id: '',
        startX: 0,
        startY: 0,
        bgImage: '',
        sliderImage: '',
    },
})

const captchaRequest = reactive<ImageCaptchaTrack>({
    bgImageWidth: 0,
    bgImageHeight: 0,
    sliderImageWidth: 0,
    sliderImageHeight: 0,
    startSlidingTime: '',
    endSlidingTime: '',
    startTime: new Date(),
    trackList: [],
})
const refresh = async () => {
    const { code, data } = await doGetCaptchaSlider()
    if (code !== 200) {
        return
    }
    initCaptcha(data)
}
watch(
    () => props.modelValue,
    (value) => {
        params.isShow = value
        value && refresh()
    },
    { immediate: true },
)
watch(
    () => params.isShow,
    (value) => emits('update:modelValue', value),
)

const initCaptcha = ({ id, captcha }: CaptchaResponse) => {
    params.sliderValue = 0
    params.captcha.id = id
    params.captcha.startX = 0
    params.captcha.startY = 0
    params.captcha.bgImage = captcha.backgroundImage
    params.captcha.sliderImage = captcha.templateImage
    captchaRequest.startTime = new Date()
    captchaRequest.bgImageWidth = captcha.backgroundImageWidth / props.scale
    captchaRequest.bgImageHeight = captcha.backgroundImageHeight / props.scale
    captchaRequest.sliderImageWidth = captcha.templateImageWidth / props.scale
    captchaRequest.sliderImageHeight = captcha.templateImageHeight / props.scale
    captchaRequest.startSlidingTime = new DateUtil().getYMDHMSs(captchaRequest.startTime)
    captchaRequest.trackList = []
}
const down = (event: any) => {
    const point = event.touches[0]
    params.captcha.startX = Math.round(point.pageX)
    params.captcha.startY = Math.round(point.pageY)
    captchaRequest.trackList.push({
        x: 0,
        y: 0,
        type: TrackType.DOWN,
        t: new Date().getTime() - captchaRequest.startTime.getTime(),
    })
}
const moving = (event: any) => {
    const point = event.touches[0]
    captchaRequest.trackList.push({
        x: Math.round(point.pageX) - params.captcha.startX,
        y: Math.round(point.pageY) - params.captcha.startY,
        type: TrackType.MOVE,
        t: new Date().getTime() - captchaRequest.startTime.getTime(),
    })
}
const up = (event: any) => {
    const point = event.changedTouches[0]
    captchaRequest.endSlidingTime = new DateUtil().getYMDHMSs(new Date())
    captchaRequest.trackList.push({
        x: Math.round(point.pageX) - params.captcha.startX,
        y: Math.round(point.pageY) - params.captcha.startY,
        type: TrackType.UP,
        t: new Date().getTime() - captchaRequest.startTime.getTime(),
    })
    props.doSubmit(HavesmsType()).then((response) => {
        const { code, msg } = response
        if (code === 200) {
            emits('success', response)
            return
        }
        msg && uni.showToast({ title: msg, icon: 'none' })
        refresh()
        return
    })
}
const HavesmsType = () => {
    if (props.smsType) {
        return {
            form: props.getForm(),
            id: params.captcha.id,
            captchaTrack: captchaRequest,
            smsType: props.smsType,
        } as CaptchaRequest<any>
    }
    return {
        form: props.getForm(),
        id: params.captcha.id,
        captchaTrack: captchaRequest,
    } as CaptchaRequest<any>
}
</script>

<style scoped></style>
